home *** CD-ROM | disk | FTP | other *** search
/ Network Supervisor's Toolkit / Network Supervisor's Toolkit.iso / btrieve / breset / breset.cpp next >
C/C++ Source or Header  |  1996-07-10  |  18KB  |  467 lines

  1. /*
  2.    BRESET.CPP V1.2
  3.    ===============
  4.    Date Created  : 1/18/93
  5.    Created by    : John Leon
  6.    Dates Modified: 1/28/93 - added batch mode switch (see below)
  7.                    2/5/94  - minor cosmetic changes to code
  8.    Last Mod by   : John Leon
  9.    Tools Used    : 1.) Borland C++ 3.1
  10.                    2.) Netware C Interface for DOS
  11.                    3.) BTC Class Library V1.8
  12.                    4.) Novell's Brequest
  13.    Model         : SMALL.
  14.    Purpose       : To do a Btrieve reset on one of the following:
  15.                    1.) Your workstation (specify -1 on command line),
  16.                    2.) A single workstation (by specifying connection #), or
  17.                    3.) All workstations on a network (no command line para-
  18.                        meter and no BRESET.NOT file in default directory),
  19.                    4.) All but those in a list (we'll exclude ALL connections
  20.                        for each name in the list), by specifying no command
  21.                        line parameter and having an ascii file named
  22.                        BRESET.NOT in the current directory.  This file must
  23.                        contain the user names (case not significant) of all
  24.                        those to be excluded from reset.
  25.    Requirements  : 1.) Must have Brequest loaded (and obviously must have the
  26.                        Btrieve NLM running on your server).
  27.                    2.) MUST be run from a network drive,
  28.                    3.) User running this program must have supervisory rights
  29.                        in the directory from which this program is run, and
  30.                    4.) User must have console operator privileges.
  31.    Comments      : 1.) See declaration of BTRV() in BTC.HPP.
  32.                    2.) A "batch mode" switch exists (pass a parameter of /b)
  33.                        to bypass the warning mechanism when performing #3 or
  34.                        #4 under PURPOSE, which would otherwise require a user
  35.                        response.
  36.                    3.) As written, program supports only versions of Netware
  37.                        up to 250 connections.  More specifically, there is
  38.                        a limit on how many connections to exclude from reset
  39.                        equal to EXCLUDELIMIT.
  40. */
  41.  
  42.  
  43. #include <stdlib.h>
  44. #include <stdio.h>
  45. #include <string.h>
  46. #include <dir.h>        //For getdisk().
  47. #include <conio.h>      //For wherex(), wherey(), gotoxy(), clreol().
  48. #include <io.h>         //For access().
  49. extern "C"  {
  50. #include <nwconn.h>
  51. #include <nwdir.h>
  52. #include <ntt.h>
  53. #include <nwconsol.h>
  54. #include <nwbindry.h>
  55. }
  56. #pragma hdrstop
  57. #include "btc.hpp"      //For BtrieveIsLoaded(), CreateBTFile(), and classes
  58.                         //CFileSpec and BFile.
  59.  
  60.  
  61. /* DEFINES & CONSTANTS */
  62. /* ------------------------------------------------------------------------ */
  63. #define TEMPFILE "Breset.BTR"
  64. #define EXCLUDEFILE "Breset.NOT"
  65. #define SUPERVISOR_DIR_RIGHTS_386 0x0100
  66. const int USERNAMELENGTH = 48, EXCLUDELIMIT = 250, MAXCONNECTIONS = 250;
  67.  
  68.  
  69. /* GLOBALS */
  70. /* ------------------------------------------------------------------------ */
  71. char PositionBlock[128], FileBuffer[5];
  72. int  BufferSize = 5;
  73. WORD myConnNumber;
  74.  
  75.  
  76. /* PROTOTYPES */
  77. /* ------------------------------------------------------------------------ */
  78. int  UserIsLoggedIn();
  79. int  CheckRights();
  80. int  MakeBTRNLMConnection();
  81. int  SecondChance();
  82. int  ResetWithExcludeList();
  83. void ResetAllOtherStations();
  84. int  ResetSingleStation(WORD connNumber);
  85. int  PerformOneReset(const char *stationNumberString);
  86. int  ConnectionIsActive(int connID);
  87.  
  88.  
  89. /* MAIN */
  90. /* ======================================================================== */
  91. int main(int argc, char *argv[])
  92. {
  93.  
  94.                                   /* Get preliminary checks out of the way. */
  95.  
  96. if ( !BtrieveIsLoaded() )  {
  97.    printf("\nPlease load Brequest before running this program\n");
  98.    exit(1);
  99. }
  100.  
  101. if ( argc > 2 )  {
  102.    printf("\nToo many command-line parameters ... aborting\n");
  103.    exit(2);
  104. }
  105.  
  106. if ( !GetDirectoryHandle(getdisk()) )  {
  107.    printf("\nThis program must be run from a network drive ... aborting\n");
  108.    exit(3);
  109. }
  110.                                   /* Save connection ID of PC running the
  111.                                      program.  May need it later. */
  112.  
  113. myConnNumber = GetConnectionNumber();
  114. if ( !myConnNumber )  {
  115.    printf("\nThis program requires a Novell network connection, supervisor\n");
  116.    printf("privileges in the current directory, console operator privileges,\n");
  117.    printf("and must be run from a network drive ... aborting\n");
  118.    exit(4);
  119. }
  120.  
  121. if ( !UserIsLoggedIn() )  {
  122.    printf("\nYou must be logged into your network to run this program\n");
  123.    exit(5);
  124. }
  125.  
  126.                                   /* OK ... Have confirmed user is logged into
  127.                                      the net, has Btrieve loaded, and has
  128.                                      default drive set to a remote (network)
  129.                                      drive.  Now confirm they have supervisor
  130.                                      directory rights in the default direc-
  131.                                      tory, that the mapped volume is not just
  132.                                      remote but is on a Netware 3.0+ server,
  133.                                      and that they have console operator
  134.                                      security equivalence. */
  135.  
  136. if ( CheckConsolePrivileges() || CheckRights() )  {
  137.    printf("You have insufficient network rights to run this program.\n");
  138.    printf("This program requires console operator privilege level and\n");
  139.    printf("supervisory rights to the current directory ... aborting.\n");
  140.    exit(6);
  141. }
  142.  
  143.                                    /* Do just enough Btrieve I/O to get a
  144.                                       Btrieve NLM connection.  Create a
  145.                                       Btrieve file on the fly, open it in
  146.                                       exclusive mode, close it, then delete
  147.                                       the darn thing. */
  148.  
  149. if ( MakeBTRNLMConnection() )  {
  150.    printf("\nCould not confirm your own connection to BTRIEVE NLM"
  151.           " ... aborting\n");
  152.    exit(7);
  153. }
  154.  
  155.                                 /* If an exclusion list (BRESET.NOT) exists,
  156.                                    be prepared to process it. */
  157.  
  158. boolean excludeListPresent = (access(EXCLUDEFILE, 0) == 0) ? true : false;
  159.  
  160.                                 /* Here's the main switch.  Could get 1 of
  161.                                    following 4 cases, so act accordingly!
  162.                                    BRESET -1  (reset yourself)
  163.                                    BRESET xxx (xxx = a connection number)
  164.                                    BRESET     (BRESET.NOT file present or not)
  165.                                    BRESET /B  (batch mode - no warnings) */
  166. switch (argc)  {
  167.    case 1:  if ( !SecondChance() )  {  // No parameter given, so give warning.
  168.                if ( excludeListPresent )
  169.                   ResetWithExcludeList();
  170.                else  {
  171.                   ResetAllOtherStations();
  172.                   ResetSingleStation(myConnNumber);
  173.                }
  174.             }
  175.             break;
  176.    case 2:  char argv1[10];
  177.             strcpy(argv1, argv[1]);
  178.             if ( strlen(argv1) > 3 )  {
  179.                printf("\nInvalid command line parameter ... aborting\n");
  180.                break;
  181.             }
  182.             strupr(argv1);
  183.             if ( (!strncmp(argv1, "/B", 2)) || (!strncmp(argv1, "-B", 2)) ||
  184.                  (!strncmp(argv1, "B", 1)) )  {
  185.                // We're in batch mode.  No warnings, Jack.
  186.                if ( excludeListPresent )
  187.                   ResetWithExcludeList();
  188.                else  {
  189.                   ResetAllOtherStations();
  190.                   ResetSingleStation(myConnNumber);
  191.                }
  192.                break;
  193.             }
  194.             // Not in batch mode, so test for parameter being -1 or a valid
  195.             // connection, and just do it.
  196.             PerformOneReset(argv1);
  197.             break;
  198.    default: printf("\nUnexpected program condition ... aborting\n");
  199.    }
  200.  
  201. return 0;
  202. }  //end MAIN
  203.  
  204.  
  205. /* FUNCTION DEFINITIONS */
  206. /* ------------------------------------------------------------------------ */
  207.  
  208.                                       /* Create a Btrieve file on the fly,
  209.                                          open it, close it, then delete it.
  210.                                          This action establishes the required
  211.                                          connection with the Btrieve NLM. */
  212. int MakeBTRNLMConnection()  {
  213.    //Create an arbitrary file of record length 5, page size 512, no keys.
  214.    CFileSpec *fSpec = new CFileSpec(5, 512, 0, NULL);
  215.    BStatus = CreateBTFile(TEMPFILE, fSpec->Specs);
  216.    delete fSpec;
  217.    if ( BStatus )
  218.       return 1;
  219.    //Open the new file in exclusive mode, no owner name, data buffer 5 bytes.
  220.    //Destructor called when object deleted will close the file.
  221.    BFile *resetBTR = new BFile(TEMPFILE, Exclusive, "", 5);
  222.    delete resetBTR;
  223.    remove(TEMPFILE);
  224.    return (BStatus ? 2 : 0);
  225. }
  226.  
  227.                                 /* Reset all connections NOT associated with
  228.                                    usernames in the EXCLUDEFILE.  If a user
  229.                                    name in the EXCLUDEFILE has multiple
  230.                                    connections, NONE of the connections for
  231.                                    that user name will be reset. */
  232.  
  233. int ResetWithExcludeList()  {
  234.    //Have previously confirmed that EXCLUDEFILE is present, but safety first.
  235.    FILE *excludeFile;
  236.    if ( (excludeFile = fopen(EXCLUDEFILE, "rt")) == NULL )  {
  237.       printf("\nError opening %s ... aborting\n", EXCLUDEFILE);
  238.       return 1;
  239.    }
  240.  
  241.    char  excludeSingleName[USERNAMELENGTH];
  242.    int   Counter = 0, numConnsExcluded = 0;
  243.    WORD  timesUserConnected;
  244.    WORD *excludeConnList = new WORD[EXCLUDELIMIT]; //Array of 250 conn numbers,
  245.                                                    //enough to hold max #
  246.                                                    //of connections to exclude.
  247.    printf("\n    ** EXCLUDED FROM RESET **\n"
  248.             "---------------------------------\n");
  249.    while ( (fgets(excludeSingleName, USERNAMELENGTH, excludeFile) != NULL) &&
  250.            (Counter < EXCLUDELIMIT) )  {
  251.       //Get rid of the cr/lf combo at end of string read.
  252.       excludeSingleName[strlen(excludeSingleName)-1] = '\0';
  253.       strupr(excludeSingleName);
  254.       if ( GetObjectConnectionNumbers(excludeSingleName,
  255.                                       OT_USER,
  256.                                       Ã—UserConnected,
  257.                                       &excludeConnList[numConnsExcluded],
  258.                                       MAXCONNECTIONS) == 0 )
  259.          if ( timesUserConnected )
  260.             printf("%s on %u connections\n", excludeSingleName,
  261.                                              timesUserConnected);
  262.       numConnsExcluded += timesUserConnected;
  263.       Counter++;
  264.       }
  265.    fclose(excludeFile);
  266.    if ( !Counter )  {
  267.       printf("Program aborted ... \n"
  268.              "Could not interpret data in file %s", EXCLUDEFILE);
  269.       return 2;
  270.    }
  271.    printf("---------------------------------\n"
  272.           "Total # excluded connections: %d\n", numConnsExcluded);
  273.  
  274.    boolean resetSelf = true, okToReset;     //Assume OK to reset self for now.
  275.  
  276.    for (Counter = 0; Counter < numConnsExcluded; Counter++)  {
  277.       if ( myConnNumber == excludeConnList[Counter] )  {
  278.          resetSelf = false;
  279.          break;
  280.       }
  281.    }
  282.  
  283.    FILE_SERV_INFO serverInfo;
  284.    GetServerInformation(sizeof(serverInfo), &serverInfo);
  285.  
  286.    printf("\nResetting connection # ");
  287.    int x = wherex(), y = wherey();
  288.    int Counter1;
  289.  
  290.    for ( Counter = 1; Counter < (serverInfo.maxConnectionsSupported+1); Counter++ )  {
  291.  
  292.       if ( Counter != myConnNumber )  {     //Don't reset yourself mid-stream!
  293.          Counter1 = 0;
  294.          okToReset = true;
  295.  
  296.          //hmmm...potentially gotta traverse entire exclude list for each valid
  297.          //conn number from 1 to maxConnectionsSupported just to see if it is
  298.          //in the (unsorted) list of connections to be excluded ... but at
  299.          //least we break if it's found in list before end of list.
  300.  
  301.                                   /* Important here to use EXCLUDELIMIT versus
  302.                                      server's max # connections, as one can
  303.                                      have a LARGE number of login IDs that has
  304.                                      no relation to server's conn limit; thus,
  305.                                      the exclude file can be larger than #
  306.                                      connections permitted. */
  307.  
  308.          for (Counter1; Counter1 < EXCLUDELIMIT; Counter1++)  {
  309.             if ( Counter == excludeConnList[Counter1] )  {
  310.                okToReset = false;
  311.                break;
  312.             }
  313.          }
  314.          if ( okToReset )  {
  315.             gotoxy(x, y);
  316.             printf("%d", Counter);
  317.             BTRV(BReset, PositionBlock, &FileBuffer, &BufferSize,
  318.                  (void *)&Counter, -1);
  319.          }
  320.       }
  321.    }
  322.  
  323.    gotoxy(1,y);
  324.    clreol();
  325.    printf("Done.\n");
  326.    delete [] excludeConnList;
  327.  
  328.    if ( resetSelf )
  329.       ResetSingleStation(myConnNumber);
  330.    return 0;
  331. }
  332.  
  333.                                 /* To reset all stations but your own. */
  334. void ResetAllOtherStations()  {
  335.    FILE_SERV_INFO serverInfo;
  336.    GetServerInformation(sizeof(serverInfo), &serverInfo);
  337.    printf("\nResetting connection # ");
  338.    int x = wherex(), y = wherey();
  339.    for ( int Counter = 1; Counter < (serverInfo.maxConnectionsSupported+1); Counter++ )
  340.       if ( Counter != myConnNumber )  {
  341.          gotoxy(x, y);
  342.          printf("%d", Counter);
  343.          BTRV(BReset, PositionBlock, &FileBuffer, &BufferSize, (void *)&Counter, -1);
  344.       }
  345.    gotoxy(1,y);
  346.    clreol();
  347.    printf("Done.\n");
  348. }
  349.  
  350.  
  351. int ResetSingleStation(WORD connNumber)  {
  352.    BStatus = BTRV(BReset, PositionBlock, &FileBuffer, &BufferSize,
  353.                   (void *)&connNumber, -1);
  354.    if ( !BStatus )  {
  355.       printf("\nConnection # %u has been reset\n", connNumber);
  356.       return 0;
  357.    }
  358.    else  {
  359.       printf("\nError in attempt to reset connection # %u\n", connNumber);
  360.       printf("Btrieve status code: %d\n", BStatus);
  361.       return BStatus;
  362.    }
  363. }
  364.  
  365.  
  366. int CheckRights()  {
  367.  
  368.    BYTE currentDrive = (BYTE)getdisk(), dirHandle;
  369.    WORD serverConnID, dirRights;
  370.    int cCode;
  371.  
  372.    GetDriveInformation(currentDrive, &serverConnID, &dirHandle);
  373.  
  374.    if (!IsV3Supported(serverConnID))  {
  375.       printf("\nThis program requires Netware 386 3.0 or higher on current drive.\n");
  376.       return 1;
  377.    }
  378.  
  379.    if ( (cCode = GetEffectiveRights(serverConnID, dirHandle, "",
  380.                                     &dirRights) ) != 0 )  {
  381.       printf("\nCannot determine your directory rights.  Code: %d\n", cCode);
  382.       return 2;
  383.    }
  384.  
  385.    if ( (dirRights & SUPERVISOR_DIR_RIGHTS_386) != SUPERVISOR_DIR_RIGHTS_386 )  {
  386.      printf("\nYou have insufficient directory rights to run this program.\n");
  387.      return 3;
  388.    }
  389.  
  390. return 0;
  391. }
  392.  
  393.  
  394. int ConnectionIsActive(int connID)  {
  395.    char userName[USERNAMELENGTH];
  396.    long objID;
  397.    WORD objType;
  398.    BYTE loginTime[7];
  399.    GetConnectionInformation(connID, userName, &objType, &objID, loginTime);
  400.    return ( objID ? 1 : 0 ); //objID of 0 means no object logged in on connID
  401. }
  402.  
  403.  
  404. int UserIsLoggedIn()  {          //Returns 0 if user not logged in to network.
  405.    char userName[USERNAMELENGTH];
  406.    long objID;
  407.    WORD objType;
  408.    BYTE loginTime[7];
  409.    if ( !GetConnectionInformation(myConnNumber, userName, &objType,
  410.                                   &objID, loginTime) )
  411.       return 1;
  412.    else
  413.       return 0;    //Flip response for lexical sense ...such that
  414. }                  //!UserIsLoggedIn makes sense.
  415.  
  416.  
  417. int SecondChance()  {
  418.    printf("\nWARNING!!  If you continue, ALL workstations on your network\n");
  419.    printf(           "will receive a Btrieve reset, excluding only those\n");
  420.    printf(           "user names present in the %s file.  If you suspect \n",
  421.           EXCLUDEFILE);
  422.    printf(           "ANY users are in Btrieve applications that should not\n");
  423.    printf(           "be reset, you MUST ANSWER THE FOLLOWING PROMPT \"NO\"!!\n");
  424.    printf("\nRESET WORKSTATIONS? (Y/N): \a\a");
  425.    char response[5];
  426.    gets(response);
  427.    strupr(response);
  428.    if ( !strlen(response) || (response[0] != 'Y') )  {
  429.       printf("\nOperation aborted ...\n");
  430.       return 1;
  431.    }
  432.    return 0;
  433. }
  434.  
  435.  
  436. int PerformOneReset(const char *stationNumberString)  {
  437.    int stationNumber;
  438.    if ( (stationNumber = atoi(stationNumberString)) == 0 )  {
  439.       printf("\nInvalid parameter ... aborting\n");
  440.       return 1;
  441.    }
  442.    if ( stationNumber == myConnNumber )  {
  443.       printf("\nERROR: You have selected your own connection ID for reset.\n");
  444.       printf("       If you wish to reset your own connection, enter -1 and\n");
  445.       printf("       NOT your actual connection number.\n");
  446.       return 2;
  447.    }
  448.    if ( stationNumber == -1 )  {
  449.       printf("\nResetting your connection ... \n");
  450.       ResetSingleStation(myConnNumber);
  451.       return 0;
  452.    }
  453.    if ( stationNumber > 0 && stationNumber < 251 )
  454.       if ( ConnectionIsActive(stationNumber) )  {
  455.          ResetSingleStation(stationNumber);
  456.          return 0;
  457.       }
  458.       else  {
  459.          printf("\nConnection #%d is not in use ... aborting\n", stationNumber);
  460.          return 3;
  461.       }
  462.    else  {
  463.       printf("\nInvalid connection number specified ... aborting\n");
  464.       return 4;
  465.    }
  466. }
  467.